#ifndef CAPSULE_H
#define CAPSULE_H

#include "Particle.h"

/// @file Capsule.h
/// @brief represents a capsule rigid body
/// @author Perseedoss Rajiv
/// @version 1.0
/// @date 26.07.11
/// Revision History :
/// Initial Version 26.07.11
/// @class Capsule
/// @brief specialised particle that represent a capsule

class Capsule : public Particle
{
public:
    /// @brief ctor
    Capsule();

    /// @brief copy ctor
    /// @param[in] _capsule the copied object
    Capsule(const Capsule& _capsule);

    /// @brief ctor
    /// @param[in] _id the id of the capsule
    /// @param[in] _mass the mass of the capsule
    /// @param[in] _centerPosition the center position of the capsule
    /// @param[in] _colour the colour of the capsule
    /// @param[in] _radius the radius of the capsule
    /// @param[in] _height the height of the capsule
    /// @param[in] _orientationVector the orientation of the capsule
    /// @param[in] _incrementAngle the increment angle for the capsule rotation
    /// @param[in] _initialAngle the initial angle of the capsule orientation
    /// @param[in] _moveable flag to determine whether capsule is static
    Capsule
        (
            const int _id,
            const ngl::Real _mass = 0,
            const ngl::Vector _centerPosition = 0,
            const ngl::Colour _colour = 0,
            const ngl::Real _radius = 0,
            const ngl::Real _height = 0,
            const ngl::Vector _orientationVector = 0,
            const ngl::Real _incrementAngle = 0,
            const ngl::Real _initialAngle = 0,
            const bool _moveable = true
        );

    /// @brief dtor
    ~Capsule();

    /// @brief return the orientation vector
    inline ngl::Vector getOrientationVector() const { return m_orientationVector; }

    /// @brief rotates the capsule at each iteration
    void updateRotation();

    /// @brief return the increment angle
    inline float getIncrementAngle() const { return m_incrementAngle; }

    /// @brief return the angle of rotation
    inline float getAngle() const { return m_angle; }

    /// @brief return the initial angle of orientation
    inline float getInitialAngle() const { return m_initialAngle; }

    /// @brief return the height
    inline ngl::Real getHeight() const { return m_height; }

    /// @brief return the first endpoint of the capsule
    inline ngl::Vector getPoint1() const { return m_position - (m_height * m_orientationVector); }

    /// @brief return the second endpoint of the capsule
    inline ngl::Vector getPoint2() const { return m_position + (m_height * m_orientationVector); }

    /// @brief set the increment angle
    /// @param[in] _v the new increment angle
    inline void setIncrementAngle(const ngl::Real _v) { m_incrementAngle = _v; }


private:
    /// @brief orientation vector connecting 2 endpoints
    ngl::Vector m_orientationVector;

    /// @brief half height from center position
    ngl::Real m_height;

    /// @brief angle of rotation
    ngl::Real m_angle;

    /// @brief increment angle
    ngl::Real m_incrementAngle;

    /// @brief initial angle of orientation
    ngl::Real m_initialAngle;

};

#endif // CAPSULE_H
